package Phase1;

import Phase1.RegexParser.RegexFileParser;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Scanner;
import java.nio.file.StandardCopyOption.*;

/**
 * Created with IntelliJ IDEA.
 * User: Alvin
 * Date: 12/8/12
 * Time: 5:07 PM
 * To change this template use File | Settings | File Templates.
 */
public class RDPUtility {
    public static void main(String[] args) {
        try {
            recursivereplace("ll1test.txt","ll1output.txt","Red","ReR");
        }
        catch(Exception e) {
            System.out.println("Shit's jank");
        }
    }

    public static boolean checkInput(String regex, String testInput) throws Exception {
        RegexFileParser rdp = new RegexFileParser("null",regex);
        String currentToken;
        int lineNo = 0;
        int startIndex = 0;
        int endIndex = 1;
        boolean inToken = false;
        startIndex = 0;
        endIndex = 1;
        inToken = false;
        while(startIndex < testInput.length()) {
            if(endIndex == testInput.length() + 1) {
                currentToken = testInput.substring(startIndex, endIndex-1);
                if(rdp.MatchTokenExclusive(currentToken) != null) {
                    return false;
                }
                break;
            }
            currentToken = testInput.substring(startIndex, endIndex);
            if(rdp.MatchToken(currentToken) != null) {
                inToken = true;
                endIndex++;
            }
            else {
                if(inToken) {
                    if(rdp.MatchTokenExclusive(currentToken.substring(0,currentToken.length()-1)) != null) {
                        return false;
                    }
                    else {
                        startIndex++;
                        inToken = false;
                    }
                }
                else {
                    if(endIndex-startIndex > 1) {
                        startIndex++;
                    }
                    else {
                        startIndex++;
                        endIndex++;
                    }
                }
            }
        }
        return true;
    }

    public static ArrayList<MatchObject> find(String filename, String regex) {
        try {
            RegexFileParser rdp = new RegexFileParser(filename, regex);
            ArrayList<MatchObject> matchList = new ArrayList<MatchObject>();
            File file = new File(filename);
            Scanner in = new Scanner(file);
            String currentLine, currentToken;
            int lineNo = 0;
            int startIndex = 0;
            int endIndex = 1;
            boolean inToken = false;
            while(in.hasNext()) {
                currentLine = in.nextLine();
                startIndex = 0;
                endIndex = 1;
                inToken = false;
                while(startIndex < currentLine.length()) {
                    if(endIndex == currentLine.length() + 1) {
                        currentToken = currentLine.substring(startIndex, endIndex-1);
                        if(rdp.MatchTokenExclusive(currentToken) != null) {
                            MatchObject obj = new MatchObject(filename, currentToken, lineNo, startIndex, endIndex-2);
                            matchList.add(obj);
                        }
                        break;
                    }
                    currentToken = currentLine.substring(startIndex, endIndex);
                    if(rdp.MatchToken(currentToken) != null) {
                        inToken = true;
                        endIndex++;
                    }
                    else {
                        if(inToken) {
                            if(rdp.MatchTokenExclusive(currentToken.substring(0,currentToken.length()-1)) != null) {
                                MatchObject obj = new MatchObject(filename, currentToken.substring(0,currentToken.length()-1), lineNo, startIndex, endIndex-2);
                                matchList.add(obj);
                                inToken = false;
                                startIndex = endIndex-1;
                            }
                            else {
                                startIndex++;
                                inToken = false;
                            }
                        }
                        else {
                            startIndex++;
                            endIndex++;
                        }
                    }
                }
                lineNo++;
            }
            in.close();
            return matchList;
        }
        catch (Exception e) {
            System.out.println("Shit's extra jank");
            return null;
        }
    }

    public static void replace(String fileInName, String fileOutName, String regex, String replaceString) {
        try {
            ArrayList<MatchObject> matches = find(fileInName, regex);
            File outFile = new File(fileOutName);
            outFile.createNewFile();
            FileWriter out = new FileWriter(outFile);
            File inFile = new File(fileInName);
            Scanner in = new Scanner(inFile);
            String currentLine;
            int lineNo = 0;
            int buffer = 0;
            while(in.hasNext()) {
                currentLine = in.nextLine();
                buffer = 0;
                for(MatchObject match : matches) {
                    if(lineNo == match.line) {
                        currentLine = currentLine.substring(0,match.start_index-buffer) + replaceString + currentLine.substring(match.end_index+1-buffer);
                        buffer += match.end_index-match.start_index+1-replaceString.length();
                    }
                }
                out.write(currentLine + "\r\n");
                lineNo++;
            }
            out.close();
            in.close();
        }
        catch (Exception e) {
            System.out.println("Shit's mega jank");
        }
    }

    public static void recursivereplace(String fileInName, String fileOutName, String regex, String replaceString) {
        try {
            if(checkInput(regex,replaceString)) {
                boolean matchFound = false;
                String intermediateOutFile = "temp.txt";
                ArrayList<MatchObject> matches = find(fileInName, regex);
                File outFile = new File(fileOutName);
                outFile.createNewFile();
                FileWriter out = new FileWriter(outFile);
                File inFile = new File(fileInName);
                Scanner in = new Scanner(inFile);
                String currentLine;
                int lineNo = 0;
                int buffer = 0;
                while(in.hasNext()) {
                    currentLine = in.nextLine();
                    buffer = 0;
                    for(MatchObject match : matches) {
                        if(lineNo == match.line) {
                            matchFound = true;
                            currentLine = currentLine.substring(0,match.start_index-buffer) + replaceString + currentLine.substring(match.end_index+1-buffer);
                            buffer += match.end_index-match.start_index+1-replaceString.length();
                        }
                    }
                    out.write(currentLine + "\r\n");
                    lineNo++;
                }
                out.close();
                in.close();
                while(matchFound) {
                    matchFound = false;
                    matches = find(fileOutName, regex);
                    outFile = new File(intermediateOutFile);
                    outFile.createNewFile();
                    out = new FileWriter(outFile);
                    inFile = new File(fileOutName);
                    in = new Scanner(inFile);
                    lineNo = 0;
                    buffer = 0;
                    while(in.hasNext()) {
                        currentLine = in.nextLine();
                        buffer = 0;
                        for(MatchObject match : matches) {
                            if(lineNo == match.line) {
                                matchFound = true;
                                currentLine = currentLine.substring(0,match.start_index-buffer) + replaceString + currentLine.substring(match.end_index+1-buffer);
                                buffer += match.end_index-match.start_index+1-replaceString.length();
                            }
                        }
                        out.write(currentLine + "\r\n");
                        lineNo++;
                    }
                    out.close();
                    in.close();
                    inFile.delete();
                    outFile.renameTo(inFile);
                }
            }
            else {
                System.out.println("Invalid input - infinite recursive replace detected.");
            }
        }
        catch (Exception e) {
            System.out.println("Shit's ultra jank");
        }
    }
}
